﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using NHibernate;
using NHibernate.Cfg;

namespace sap2exact
{
    public class Hibernator
    {
        private static ISessionFactory sessionFactory;


        public Hibernator() {
            if (sessionFactory == null)
            {
                var configuration = new Configuration();
                configuration.Configure();

                // configuration.AddAssembly(typeof(Domain.TestData).Assembly);
                configuration.AddAssembly(typeof(Domain.ExportData).Assembly);
                /*
                NHibernate.JetDriver.JetDialect jd = new NHibernate.JetDriver.JetDialect();
                //NHibernate.ByteCode.LinFu.ProxyFactoryFactory pff = new NHibernate.ByteCode.LinFu.ProxyFactoryFactory();
                NHibernate.ByteCode.Castle.ProxyFactoryFactory pff = new NHibernate.ByteCode.Castle.ProxyFactoryFactory();
                */
                sessionFactory = configuration.BuildSessionFactory();

                sessionFactory.OpenSession();

                NHibernate.Tool.hbm2ddl.SchemaExport schema = new NHibernate.Tool.hbm2ddl.SchemaExport(configuration);
                schema.Create(false, true);

            }
        }

        public void Save(Domain.ExportData data) {
            //Add a Customer to the datastore
 
            //'sessionFactory' is a thread-safe object built once per application lifetime (can take seconds to build)
            //based on configuration files which control how database tables are mapped to C# objects
            //(e.g. which property maps to which column in a database table)
            //
            //'session' is not thread safe and fast to obtain and can be thought of as a connection to the database
            using (var session = sessionFactory.OpenSession()) 
            {
                //transaction represents a db transaction
                using (ITransaction transaction = session.BeginTransaction()) 
                {
                    //The line below adds the customer to NHibernate's list of objects to insert to the database
                    //but it doesn't execute SQL insert command at this stage*.
                    //*if the Id field is generated by the database (e.g. an auto-incremented number) 
                    //then NHibernate will execute SQL INSERT when .Save is called  
                    session.Save(data);
 
                    //The call below will execute the SQL INSERT and commit the transaction
                    transaction.Commit();
                }
            }
        }


        public Domain.ExportData Load() {
            //Retrieve the Customer from the database, modify the record and update the database
            using (var session = sessionFactory.OpenSession())
            using (ITransaction transaction = session.BeginTransaction())
            {
                //session's Query returns IQueryable<Customer>.
                //Only when .FirstOrDefault is called will NHibernate execute the SQL query  
                // Domain.ExportData data = session.QueryOver<Domain.ExportData>().Where(c => c.Token == token).FirstOrDefault();
                var list = session.CreateCriteria(typeof(Domain.ExportData)).List();

                return (Domain.ExportData) list[0];
            }
        }
    }
}
